package cc.rengu.oltp.utility.util;

import java.io.*;

/**
 * The type Serialize util.
 */
public class SerializeUtil {
    /**
     * The type Look ahead object input stream.
     */
    class LookAheadObjectInputStream extends ObjectInputStream {
        private String className;

        /**
         * Instantiates a new Look ahead object input stream.
         *
         * @param inputStream the input stream
         * @param className   the class name
         * @throws IOException the io exception
         */
        public LookAheadObjectInputStream(InputStream inputStream, String className)
                throws IOException {
            super(inputStream);
            this.className = className;
        }

        @Override
        protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
            /** 存在继承关系时无法用equals判断，因此暂时不做类型检查
             if (!desc.getName().equals(className)) {
             throw new InvalidClassException(
             "Unauthorized deserialization attempt",
             desc.getName());
             }
             **/
            return super.resolveClass(desc);
        }
    }

    /**
     * Serialize byte [ ].
     *
     * @param obj the obj
     * @return the byte [ ]
     * @throws IOException the io exception
     */
    public static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            byte[] buffer = baos.toByteArray();
            oos.close();
            baos.close();
            return buffer;
        } catch (IOException ioe) {
            throw ioe;
        } finally {
            if (null != baos) {
                baos.close();
            }
            if (null != oos) {
                oos.close();
            }
        }

    }

    /**
     * Unserialize object.
     *
     * @param buffer the buffer
     * @param clasz  the clasz
     * @return the object
     * @throws IOException            the io exception
     * @throws ClassNotFoundException the class not found exception
     */
    public static Object unserialize(byte[] buffer, Class clasz) throws IOException, ClassNotFoundException {
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        try {
            bais = new ByteArrayInputStream(buffer);
            ois = new SerializeUtil().new LookAheadObjectInputStream(bais, clasz.getName());
            Object obj = ois.readObject();
            ois.close();
            bais.close();
            return obj;
        } catch (IOException ioe) {
            throw ioe;
        } catch (ClassNotFoundException cnfe) {
            throw cnfe;
        } finally {
            if (null != bais) {
                bais.close();
            }
            if (null != ois) {
                ois.close();
            }
        }
    }
}